<!--
 * @Author: yuanweijiang
 * @Date: 2024-01-04 10:08:05
 * @LastEditors: XHM
-->
<template>
	<el-dialog :title="title" width="600" v-model="visible" :close-on-click-modal="false" :destroy-on-close="true" draggable @close="closeDialog">
		<div v-if="progressName">
			<el-progress :percentage="percentage"></el-progress>
		</div>
		<el-form ref="menuDialogFormRef" :model="form" :rules="rules" label-width="100px" v-else>
			<el-form-item label="文件类型" prop="type">
				<div class="flex w-full justify-between">
					<p
						class="flex justify-center items-center tabList cursor-pointer gap-2"
						v-for="(item, index) in tabList"
						:key="item.text"
						@click="tabHandle(item, index)"
						:class="active == index ? 'actived' : ''"
					>
						<i class="iconfont" :class="item.icon"></i>
						<span>{{ item.text }}</span>
					</p>
				</div>
			</el-form-item>
			<el-form-item prop="fileList">
				<div class="flex" v-if="!singleFilePart.fileList.length > 0">
					<el-upload
						v-model:file-list="singleFilePart.fileList"
						class="upload-demo"
						:limit="1"
						:headers="headers"
						accept=".zip"
						:show-file-list="false"
						:on-change="selectSinglePartFile"
						:before-upload="beforeUpload"
						:auto-upload="false"
					>
						<el-button icon="CirclePlus" type="primary">添加文件</el-button>
					</el-upload>
					<span style="color: #b9c2cd" class="text-sm ml-2">{{ uploadTip }}</span>
				</div>
				<div v-if="singleFilePart.fileList.length > 0">{{ singleFilePart.fileName }}</div>
			</el-form-item>
			<el-form-item label="文件命名" prop="fileNameCh">
				<el-input v-model.trim="form.fileNameCh" clearable placeholder="请输入名称"></el-input>
			</el-form-item>
			<el-row :gutter="20">
				<el-col :span="12">
					<el-form-item label="所属项目" prop="projectName">
						<el-select v-model="form.projectName" placeholder="请选择项目" :suffix-icon="IconDropDown">
							<el-option v-for="item in options" :key="item.label" :label="item.label" :value="item.value" />
						</el-select>
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="数据源类型" prop="dataSourceType">
						<el-select v-model="form.dataSourceType" placeholder="请选择数据源类型" :suffix-icon="IconDropDown">
							<el-option v-for="item in dataType" :key="item.label" :label="item.text" :value="item.value" />
						</el-select>
					</el-form-item>
				</el-col>
			</el-row>
			<el-form-item />

			<el-form-item label="文件说明" prop="fileRemarks">
				<el-input v-model.trim="form.fileRemarks" type="textarea" clearable placeholder="请输入说明"></el-input>
			</el-form-item>
			<div class="text-center">
				<el-button type="primary" @click="singleFilePartUpload(menuDialogFormRef)">保存</el-button>
			</div>
		</el-form>
	</el-dialog>
</template>
<script setup lang="ts">
import { useMessage } from '/@/hooks/message';
import { ref } from 'vue';
import DropDown from '/@/assets/icons/drop-down.svg';
import { getIdProject } from '/@/api/admin/role';
import { useUserInfo } from '/@/stores/userInfo';
import { Session } from '/@/utils/storage';
import axios from 'axios';
// import { Session } from '/@/utils/storage';
const visible = ref(false);
const form = ref({});
const percentage = ref(0);
const progressName = ref(false);
const rules = ref({
	fileNameCh: [{ required: true, message: '不能为空', trigger: 'blur' }],
	projectName: [{ required: true, message: '请选择', trigger: 'blur' }],
	fileRemarks: [{ required: true, message: '不能为空', trigger: 'blur' }],
	dataSourceType: [{ required: true, message: '不能为空', trigger: 'blur' }],
});
const active = ref('0');
const menuDialogFormRef = ref('');
const accept = ref(['zip', 'rar']);
const emit = defineEmits(['refresh']);
const { proxy } = getCurrentInstance();
const options = ref([]);

const dataType = ref([
	{
		text: '点',
		value: '1',
	},
	{
		text: '线',
		value: '2',
	},
	{
		text: '面',
		value: '3',
	},
	{
		text: '栅格图层',
		value: '4',
	},
]);
const singleFilePart = ref({
	file: '',
	fileList: [],
	fileData: [],
	partNum: 0, // 总分片数
	fileName: '', // 文件名
	fileUid: '', // 文件uuid
	fileMd5: '', // 文件Md5
	isStop: false,
	randomCount: 0,
});
const fileType = ref('');
// const acceptedTypes = ref('application/octet-stream');
const tabList = ref([
	{
		text: '矢量数据',
		tip: '支持上传shp的zip文件',
		icon: 'icon-shiliangtu',
		accept: ['zip', 'rar'],
	},
	{
		text: '栅格数据',
		tip: '支持上传 GeoTIFF 类型文件',
		icon: 'icon-jiantou-',
		accept: ['tif', 'tiff'],
	},
	{
		text: '3D数据',
		tip: '支持上传3dtiles、dem、dom、glb、fbx等zip文件',
		icon: 'icon-a-3d1',
		accept: ['3dtiles', 'dem', 'dom', 'glb', 'fbx', 'zip', 'rar'],
	},
]);
const IconDropDown = {
	render: () => {
		return h('img', { src: DropDown });
	},
};
const uploadFlag = ref(true);
const headers = computed(() => {
	return {
		Accept: 'application/octet-stream',
	};
});
const uploadTip = ref('支持上传shp的zip文件');
// 定义父组件传过来的值
const props = defineProps({
	title: {
		type: String,
		default: () => '',
	},
});
//获取当前用户有哪些项目
const getInfoProject = async () => {
	const { data } = await getIdProject(useUserInfo().userInfos.roles);
	options.value = data.map((item) => {
		item.wokeSpaceName = item.wokeSpaceName !== undefined && item.wokeSpaceName !== null ? item.wokeSpaceName : '';
		item.projectNameCh = item.projectNameCh !== undefined && item.projectNameCh !== null ? item.projectNameCh : '';
		return {
			value: item.wokeSpaceName,
			label: item.projectNameCh,
		};
	});
};

getInfoProject();
//文件类型切换
const tabHandle = (item, index) => {
	active.value = index;
	uploadTip.value = item.tip;
	accept.value = item.accept;
};
//上传成功
const beforeUpload = (file: any) => {
	if (accept.value.length) {
		const fileName = file.name.split('.');
		const fileExt = fileName[fileName.length - 1];
		fileType.value = fileExt;
		const isTypeOk = accept.value.indexOf(fileExt) >= 0;
		const adminId = useUserInfo().userInfos.user.userId;
		if (!isTypeOk && adminId !== '1') {
			useMessage().error(`文件格式不正确, 请上传${accept.value.join('/')}格式文件!`);
			singleFilePart.value.fileList = [];
		}
	}
};

// 下面是单文件分片上传的一些方法
function selectSinglePartFile(file, fileList) {
	singleFilePart.value.file = file;
	singleFilePart.value.fileList = [];
	singleFilePart.value.fileList.push(file);
	singleFilePart.value.fileName = file.name;
}

//开始分片上传
async function singleFilePartUpload(forms: any) {
	if (singleFilePart.value.fileList.length <= 0) {
		return useMessage().error('请添加文件');
	}
	const chinesePattern = /[\u4e00-\u9fa5]/;
	if (chinesePattern.test(singleFilePart.value.fileName)) {
		return useMessage().error('文件名不能包含中文');
	}
	await forms.validate(async (valid) => {
		if (!valid) {
			return;
		}
		let url = proxy.baseURL + '/geoserver/file/singleFilePartUpload';
		let partSize = 5 * 1024 * 1024; // 5MB
		let totalSize = singleFilePart.value.file.size;
		singleFilePart.value.fileUid = singleFilePart.value.file.uid;
		singleFilePart.value.partNum = Math.ceil(totalSize / partSize); // 5MB一片
		progressName.value = true;
		for (let i = 0; i < singleFilePart.value.partNum; i++) {
			if (!uploadFlag.value) {
				break; // 如果 uploadFlag 为 false，跳出循环
			}
			const fileParam = new FormData();
			fileParam.append('filePart', singleFilePart.value.file.raw.slice(i * partSize, (i + 1) * partSize));
			fileParam.append('partIndex', i);
			fileParam.append('partNum', singleFilePart.value.partNum);
			fileParam.append('fileUid', singleFilePart.value.fileUid);
			fileParam.append('totalSize', totalSize);
			fileParam.append('fileService', 'linuxService');
			fileParam.append('fileType', fileType.value);
			fileParam.append('dbType', 'postgres');
			fileParam.append('fileName', singleFilePart.value.fileName);
			fileParam.append('projectName', form.value.projectName);
			fileParam.append('fileRemarks', form.value.fileRemarks);
			fileParam.append('fileNameCh', form.value.fileNameCh);
			fileParam.append('dataSourceType', form.value.dataSourceType);
			const headers = { Authorization: 'Bearer ' + Session.get('token') };
			try {
				const response = await axios({
					url: url,
					method: 'post',
					data: fileParam, //data表示参数在请求（body）中，后端可以通过流直接读取，SpringMvc可以使用RequestBody注解获取
					headers: headers,
					dataType: 'json',
				});
				// 检查响应对象是否为 undefined 或 null
				if (!response || !response.data) {
					throw new Error('服务器未返回有效响应');
				}
				const resp = response.data;

				// 打印完整的响应对象以调试
				if (resp.code !== 0) {
					throw new Error(resp.msg || '未知错误');
				}
				percentage.value = Number((((i + 1) / singleFilePart.value.partNum) * 100).toFixed(2));
				// 判断最后一个分片文件传完之后，后台检验文件上传情况
				if (i === singleFilePart.value.partNum - 1) {
					percentage.value = 100;
					progressName.value = false;
					useMessage().success('保存完成');
					visible.value = false;
					setTimeout(() => {
						emit('refresh');
						reset();
					}, 500);
				}
			} catch (error) {
				percentage.value = 0;
				progressName.value = false;
				visible.value = false;
				useMessage().error(error.message);
				uploadFlag.value = false; // 设置 uploadFlag 为 false，跳出循环
				break; // 停止上传其他分片
			}
		}
	});
}
function openDialog() {
	visible.value = true;
}
//重置表单
const reset = () => {
	form.value = {};
	singleFilePart.value.fileList = [];
};
function closeDialog() {
	uploadFlag.value = false;
	progressName.value = false;
	reset();
}
defineExpose({
	openDialog,
	reset,
});
</script>
<style scoped lang="scss">
.tabList {
	background: #eaf1ff;
	border-radius: 2px;
	color: #3156a5;
	width: 33%;
	padding: 0px 6px;
}
.actived {
	background: #3156a5;
	color: #fff;
}
</style>
